﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

 #pragma once
#include "GcmpDbCommonEdit.h"
#include "GcmpApiDeclaration.h"

namespace gcmp
{
    class ICurve3d;
    class Vector3d;
    class IPlane;
    class IPolyCurve;
    class Coordinate3d;
    /// \brief 倒圆角工具
    class GCMP_DB_COMMON_EDIT_EXPORT FilletUtils
    {
    public:
        /// \brief 检查两条曲线是否可以按照配置倒圆角，目前只支持两条非平行且共面的直线倒圆角
        /// \param[in] pFirstCurve 需倒圆角的第一条曲线
        /// \param[in] firstCurvePickPoint 需倒圆角的第一条曲线上的点
        /// \param[in] pSecondCurve 需倒圆角的第二条曲线
        /// \param[in] secondCurvePickPoint 需倒圆角的第二条曲线上的点
        /// \param[in] chamferArcRadius 倒圆角后生成的圆弧半径大小，要求大于0
        /// \param[out] pErrorMessage 不允许倒圆角的原因
        /// \return 允许倒角返回true，不允许返回false
        static bool CanFillet(const ICurve3d *pFirstCurve, const Vector3d& firstCurvePickPoint,
            const ICurve3d *pSecondCurve, const Vector3d& secondCurvePickPoint,
            double chamferArcRadius,
            std::wstring *pErrorMessage = nullptr);

        /// \brief 对两条曲线按照配置倒圆角，目前只支持两条非平行且共面的直线倒圆角；内部会先调用CanFillet接口判断是否可以倒圆角
        /// \param[in] pFirstCurve 需倒圆角的第一条曲线
        /// \param[in] firstCurvePickPoint 需倒圆角的第一条曲线上的点
        /// \param[in] pSecondCurve 需倒圆角的第二条曲线
        /// \param[in] secondCurvePickPoint 需倒圆角的第二条曲线上的点
        /// \param[in] chamferArcRadius 倒圆角后生成的圆弧半径大小，要求大于0
        /// \param[out] pChamferResult 倒圆角结果，成功有三个元素，第一个元素是第一条线倒圆角后的几何表示，第二个元素是第二条线倒圆角后的几何表示，第三个元素是补线的几何表示；失败没有元素；不可传入空指针，否则报错
        /// \param[out] pErrorMessage 不允许倒圆角的原因
        /// \return 倒角是否成功，成功返回true，失败返回false
        static bool Fillet(const ICurve3d *pFirstCurve, const Vector3d& firstCurvePickPoint,
            const ICurve3d *pSecondCurve, const Vector3d& secondCurvePickPoint,
            double chamferArcRadius,
            std::vector<OwnerPtr<ICurve3d>> *pChamferResult,
            std::wstring *pErrorMessage = nullptr);

        /// \brief 对多段线整体倒圆角
        /// \param[in] pPolyCurve 需倒圆角的第一条曲线
        /// \param[in] filletArcRadius 倒圆角后生成的圆弧半径大小，要求大于0
        /// \param[in] coordinate  多段线所在坐标系
        /// \param[out] opFilletResult 整体倒圆角后的多段线对象
        /// \param[out] pErrorMessage 不允许倒圆角的原因
        /// \return 倒角是否成功，成功返回true，失败返回false
        static bool FilletPolyCurve(const IPolyCurve* pPolyCurve,
            double filletArcRadius,
            Coordinate3d& coordinate,
            OwnerPtr<gcmp::IPolyCurve>& opFilletResult,
            std::wstring *pErrorMessage = nullptr);


        /// \brief 检查两条曲线是否可以按照配置倒圆角，目前只支持两条非平行且端点共点的直线段倒圆角
        /// \param[in] pFirstCurve 需倒圆角的第一条曲线
        /// \param[in] pSecondCurve 需倒圆角的第二条曲线
        /// \param[in] chamferArcRadius 倒圆角后生成的圆弧半径大小，要求大于0
        /// \param[out] pErrorMessage 不允许倒圆角的原因
        /// \return 允许倒角返回true，不允许返回false
        GCMP_OBSOLETE_API(2021/01/01, FilletUtils::CanFillet(const ICurve3d*, const Vector3d&,const ICurve3d*, const Vector3d&, double,std::wstring*)) static bool CanFillet(const ICurve3d *pFirstCurve,
            const ICurve3d *pSecondCurve,
            double chamferArcRadius,
            std::wstring *pErrorMessage = nullptr);

        /// \brief 对两条曲线按照配置倒圆角，目前只支持两条非平行且端点共点的直线段倒圆角；内部会先调用CanChamfer接口判断是否可以倒角
        /// \param[in] pFirstCurve 需倒圆角的第一条曲线
        /// \param[in] pSecondCurve 需倒圆角的第二条曲线
        /// \param[in] chamferArcRadius 倒圆角后生成的圆弧半径大小，要求大于0
        /// \param[out] pChamferResult 倒圆角结果，成功有三个元素，第一个元素是第一条线倒圆角后的几何表示，第二个元素是第二条线倒圆角后的几何表示，第三个元素是补线的几何表示；失败没有元素；不可传入空指针，否则报错
        /// \param[out] pErrorMessage 不允许倒圆角的原因
        /// \return 倒角是否成功，成功返回true，失败返回false
        GCMP_OBSOLETE_API(2021/01/01, FilletUtils::Fillet(const ICurve3d*, const Vector3d&, const ICurve3d*, const Vector3d&, double, std::vector<OwnerPtr<ICurve3d>>*,std::wstring*)) static bool Fillet(const ICurve3d *pFirstCurve,
            const ICurve3d *pSecondCurve,
            double chamferArcRadius,
            std::vector<OwnerPtr<ICurve3d>> *pChamferResult,
            std::wstring *pErrorMessage = nullptr);

        /// \brief 对多段线整体倒圆角
        /// \param[in] pPolyCurve 需倒圆角的第一条曲线
        /// \param[in] filletArcRadius 倒圆角后生成的圆弧半径大小，要求大于0
        /// \param[in] pProjectPlane  投影平面
        /// \param[out] opFilletResult 整体倒圆角后的多段线对象
        /// \param[out] pErrorMessage 不允许倒圆角的原因
        /// \return 倒角是否成功，成功返回true，失败返回false
        GCMP_OBSOLETE_API(2022 / 07 / 01, FilletUtils::FilletPolyCurve(const IPolyCurve*, double, Coordinate3d&, OwnerPtr<gcmp::IPolyCurve>&, std::wstring *)) static bool FilletPolyCurve(const IPolyCurve* pPolyCurve,
            double filletArcRadius,
            const gcmp::OwnerPtr<gcmp::IPlane> opProjectPlane,
            OwnerPtr<gcmp::IPolyCurve>& opFilletResult,
            std::wstring *pErrorMessage = nullptr);;
    };
}